package edu.uw.cs.cse461.sp12.OSConsoleApps;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import org.json.JSONException;
import org.json.JSONObject;

import edu.uw.cs.cse461.sp12.OS.DDNSException;
import edu.uw.cs.cse461.sp12.OS.DDNSException.DDNSNoAddressException;
import edu.uw.cs.cse461.sp12.OS.DDNSException.DDNSNoSuchNameException;
import edu.uw.cs.cse461.sp12.OS.DDNSFullName;
import edu.uw.cs.cse461.sp12.OS.DDNSRRecord;
import edu.uw.cs.cse461.sp12.OS.DDNSResolverService;
import edu.uw.cs.cse461.sp12.OS.OS;
import edu.uw.cs.cse461.sp12.OS.RPCCallerSocket;
import edu.uw.cs.cse461.sp12.util.Log;

/**
 * This application resolves a name and displays the resulting resource record.
 * It will require a bit of porting to get to work, because your DDNS application
 * api is sure not to be the same as mine.
 * <p>
 * Among the less expected changes is that I've modified the OS implementation.
 * I now require "implements OSLoadableApp" rather than the "implements OSConsoleApp"
 * that was used in the Project 3 distribution.
 * 
 * @author zahorjan
 *
 */
public class nslookup implements OSConsoleApp {
	
	private static final String TAG="nslookupConsole";
	
	/**
	 * Method required by OSLoadableApp interface
	 */
	@Override
	public String appname() { 
		return "nslookup"; 
	}
	
	/**
	 * Constructor required by OSLoadableApp interface.  There's nothing to do for this app.
	 */
	public nslookup() {
	}

	/**
	 * Method required by OSLoadableApp interface.  Again, nothing to do.
	 */
	@Override
	public void shutdown() {}
	
	/**
	 * Fetches the resource record for a name, using the locally running DDNS name resolver service.
	 * (All systems are required to run a name resolver.)
	 */
	@Override
	public void run() {
		try {
			// Eclipse doesn't support System.console()
			BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
			while ( true ) {
				String targetStr = null;
				try {
					// Get command
					System.out.print("Enter a command, or exit to exit: ");
					String command = console.readLine();
					if (command.equals("exit")) {
						break;
					}
					
					// Get hostname
					System.out.print("Enter a host name, or exit to exit: ");
					targetStr = console.readLine();
					if ( targetStr == null ) {
						targetStr = "";
					} else if (targetStr.equals("exit")) {
						break;
					}
					DDNSFullName target = new DDNSFullName(targetStr);
					
					if (command.equals("resolve")) {
						DDNSRRecord record = performCall(target);
						if (record != null){
							System.out.println(targetStr + ":  [" + record.toString() + "]");
						} else {
							System.out.println("Lookup Failed");
						}

					} else if (command.equals("register")) {
						// Get ip
						System.out.print("Enter an ip, or exit to exit: ");
						String ip = console.readLine();
						if (ip.equals("exit")) {
							break;
						}
						
						// Get port
						System.out.print("Enter an port, or exit to exit: ");
						String portStr = console.readLine();
						if (portStr.equals("exit")) {
							break;
						}
						int port = Integer.parseInt(portStr);

						// Get password
						System.out.print("Enter an password, or exit to exit: ");
						String password = console.readLine();
						if (password.equals("exit")) {
							break;
						}

						DDNSRRecord record = ((DDNSResolverService)OS.getService("ddnsresolver")).register(target, port);
						System.out.println( targetStr + ":  [" + record.toString() + "]");
					} else if (command.equals("unregister")) {
						// Get password
						System.out.print("Enter an password, or exit to exit: ");
						String password = console.readLine();
						if (password.equals("exit")) {
							break;
						}
					} else {
						System.out.println("Unknown command");
					}
				} catch (DDNSNoAddressException nae) {
					System.out.println("No address is currently assoicated with that name");
				} catch (DDNSNoSuchNameException nsne) {
					System.out.println("No such name: " + targetStr);
				} catch (Exception e) {
					System.out.println("Exception: " + e.getMessage());
					for(StackTraceElement ste : e.getStackTrace()) {
						System.out.println("\t" + ste.toString());
					}
				}
			}
		} catch (Exception e) {
			System.out.println("EchoConsole.run() caught exception: " + e.getMessage());
		}
		
	}
	
	public static DDNSRRecord performCall(DDNSFullName hostName) throws DDNSException {
		DDNSRRecord record = ((DDNSResolverService)OS.getService("ddnsresolver")).resolve(hostName);
		
		/*try {
			record = ((DDNSResolverService)OS.getService("ddnsresolver")).resolve(hostName);
		} catch (DDNSException e) {
			String errorMessage = "Could not performCall (DDNSException): " + e.getMessage();
			Log.e(TAG, errorMessage);
		}*/
			
		return record;

	}
}
